using System;
using System.Text;
using System.Drawing;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using Irc.Objects;
using Irc.Net;

namespace System.Windows.Forms
{
	/// <summary>
	/// Description of ChatTextBox.
	/// </summary>
	public class ChatTextBox : RichTextBox
	{
		private bool useIrcColors = true;
		private bool useIrcBold = true;
		private bool useIrcReverse = true;
		private bool useIrcUnderline = true;
//		private Irc.Objects.Message lastMessage;
		private Color[] ColorChart = new Color[]
			{
			    Color.White,
			    Color.Black,
			    Color.DarkBlue,
			    Color.Green,
			    Color.Red,
			    Color.Maroon,
			    Color.Purple,
			    Color.Orange,
			    Color.Yellow,
			    Color.LimeGreen,
			    Color.Aqua,
			    Color.SkyBlue,
			    Color.Blue,
			    Color.Pink,
			    Color.DarkGray,
			    Color.Gray
			};
		public ChatTextBox()
		{
			ReadOnly = true;
			BackColor = Color.White;
		}
		public bool UseIrcColors
		{
			get { return useIrcColors; }
			set { useIrcColors = value; }
		}
		public bool UseIrcBold
		{
			get { return useIrcBold; }
			set { useIrcBold = value; }
		}
		public bool UseIrcReverse
		{
			get { return useIrcReverse; }
			set { useIrcReverse = value; }
		}
		public bool UseIrcUnderline
		{
			get { return useIrcUnderline; }
			set { useIrcUnderline= value; }
		}

//		public void CreateMyBorderlessWindow()
//		{
//			this.FormBorderStyle = FormBorderStyle.None;
//			this.MaximizeBox = false;
//			this.MinimizeBox = false;
//			this.StartPosition = FormStartPosition.CenterScreen;
//			this.ControlBox = false;
//		}
		protected void SetColor(Color c)
		{
			SelectionColor = c;
		}
		protected void SetBackColor(Color c)
		{
			// Mono apparently doesn't support SelectionBackColor
			//SelectionBackColor = c;
		}
		protected void SetFontStyle(FontStyle fs)
		{
			SelectionFont = new Font(Font, fs);
		}

		public new void AppendText(string message)
		{
			// we walk down the string, setting modes as they come, and applying styles
			for(int i = 0; i < message.Length; i++)
			{
				char c = message[i];
				switch(c)
				{
					case ((char)2): // bold
						if(SelectionFont.Style == FontStyle.Bold)
							SetFontStyle(FontStyle.Regular);
						else
							SetFontStyle(FontStyle.Bold);
						break;
					case ((char)3): // set color
						int forecolor = 1;
						int backcolor = 0;
						if(Char.IsDigit(message[i+1]))
						{
							int offset = message.IndexOf(',', i, 5);
							forecolor = Int32.Parse(message.Substring(i+1, Char.IsDigit(message[i+2]) ? 2 : 1));
							if(offset != -1) // we have a back color as well
								backcolor = Int32.Parse(message.Substring(offset+1, Char.IsDigit(message[i+5]) ? 2 : 1));
							i += (forecolor >= 0 && forecolor < 10 ? 1 : 2);
							i += (offset == -1 ? 0 : (backcolor >= 0 && backcolor < 10 ? 2 : 3));
						}
						SetColor(ColorChart[forecolor]);
						SetBackColor(ColorChart[backcolor]);
						break;
					case ((char)22): // reverse
						if(SelectionColor == BackColor)
						{
							SetColor(ForeColor);
							SetBackColor(BackColor);
						}
						else
						{
							SetColor(BackColor);
							SetBackColor(ForeColor);
						}
						break;
					case ((char)15): // reset formatting
						SetColor(ForeColor);
						SetBackColor(BackColor);
						SetFontStyle(FontStyle.Regular);
						break;
					case ((char)31): // underline
						if(SelectionFont.Style == FontStyle.Underline)
							SetFontStyle(FontStyle.Regular);
						else
							SetFontStyle(FontStyle.Underline);
						break;
					default:
						base.AppendText("" + c);
						break;
				}
			}
			// reset the formatting back to the original state
			SetFontStyle(FontStyle.Regular);
			SetColor(ForeColor);
			SetBackColor(BackColor);
		}
		public void AppendMessage(Irc.Objects.Message message)
		{
			string text = String.Empty;
			if(SettingsManager.Instance.UseTimestamps == true)
				text += String.Format(Strings.TimestampText, message.Time.ToString(SettingsManager.Instance["TimestampFormat"]));
			if(message.Target != null)
				text += String.Format(
							(message is PublicMessage || message is PrivateMessage ? Strings.MessageText :
							(message is PublicAction || message is PrivateAction ? Strings.ActionText :
							(message is ServerMessage || message is ServerNotice ? Strings.NoticeText :
								Strings.ActionText))),
							message.Sender, message.Text);
			else // we assume we have a preformatted message it Target is null
				text += message.Text;
			text = text.TrimEnd(' ', '\r', '\n');
			text += "\n";
			AppendText(text);
//			lastMessage = message;
		}
	}
}
